feat(docs-next): convert legacy component docs to mdsvex#2239
Draft
dancormier wants to merge 203 commits intomainfrom
Draft
feat(docs-next): convert legacy component docs to mdsvex#2239dancormier wants to merge 203 commits intomainfrom
dancormier wants to merge 203 commits intomainfrom
Conversation
Legacy fragments each start with a page-header div (d-flex ai-start jc-space-between) containing the description paragraph and action badges (Svelte, Figma). This div was built for the old docs template, which expected it as part of the fragment. The new template provides its own header, causing the description (and action links) to appear inside the content area rather than in the header. Add extractLegacyHeader() which: - Finds the opening header div and locates its matching closing tag via a depth-counting walk (handles nested divs robustly) - Extracts description text from the .docs-copy <p> - Extracts Svelte and Figma action URLs from the badge <a> hrefs - Returns the fragment HTML with the header div removed The extracted values are returned as metadata so the new template renders description and action buttons consistently with MD-sourced pages. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
❌ Deploy Preview for stacks failed. Why did it fail? →
|
Collaborator
|
@dancormier you could potentially simplify this by getting 11ty to output in an easier to work with format like using |
The Figma badge on some pages (e.g. color-fundamentals) is hosted on svelte.stackoverflow.design (/figma/colors) rather than figma.com. URL-domain matching would incorrectly classify those links as Svelte. Replace domain-based regexes with per-badge <a>...</a> matching: iterate each badge element and identify it by the text label that follows the SVG icon (Svelte or Figma), not by the URL. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8 legacy fragments have Figma badges linking to svelte.stackoverflow.design/figma/* aliases instead of actual figma.com URLs (e.g. color-fundamentals, typography, buttons). Filter extraction to only accept figma.com URLs for the Figma button. Those 8 pages will show no Figma button until correct figma.com URLs are added to their fragments or to structure.yaml. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ages Root cause: the stacks-docs page.html Eleventy template was rendering the page description twice — once inside the header flex div and once as a standalone paragraph below it. When fragments were (re)built, both occurrences appeared in the HTML, causing two descriptions to show. Changes: - stacks-docs: remove the duplicate standalone description paragraph from page.html (the description inside the flex div is sufficient; the new template extracts it as metadata and renders it in the header) - stacks-docs-next: add a belt-and-suspenders strip in extractLegacyHeader to also remove any standalone description paragraph left over in already-built fragments - stacks-docs: replace 7 wrong Figma badge URLs that pointed to svelte.stackoverflow.design/figma/* aliases with correct figma.com project links (color-fundamentals, icons, typography, spots, buttons, tags, editor) - stacks-docs: remove figma: field from box-shadow (no Figma link intended) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
stacks-docs-next was built on top of stacks-docs, copying pre-built HTML fragments, compiled assets, and a JS bundle from stacks-docs/_site at build/dev time via scripts/copy-legacy.mjs. Since stacks-docs-next is intended to replace stacks-docs, this removes the runtime coupling: - Commit static/legacy/ directly — the 98 legacy fragment HTML files, compiled assets (docs.css, entry bundles, images), docs.js, and llms.txt are now committed as static content rather than being generated by copying from stacks-docs - Remove scripts/copy-legacy.mjs — no longer needed - Remove predev script — was only used to invoke copy-legacy.mjs - Remove stacks-docs build step from prebuild — prebuild now only builds stacks and stacks-svelte, which stacks-docs-next directly depends on - Remove unused $data alias from svelte.config.js — pointed to ../stacks-docs/_data but was never imported anywhere The static/legacy/ content is now a committed snapshot of the legacy docs. Individual fragment files can be deleted as their pages are migrated to stacks-docs-next; assets and docs.js can be cleaned up once all legacy pages have been replaced. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
These changes (page.html template fix, frontmatter Figma URL updates) belong in a separate stacks-docs PR. This branch covers stacks-docs-next only. The duplicate-description and Figma URL concerns are handled in stacks-docs-next via extractLegacyHeader and the committed fragment files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes 88 files (~10 MB) from static/legacy/ that are not referenced by stacks-docs-next or the fragment HTML files: - assets/dist/ (entire directory, ~8.1 MB) - docs.css — not loaded by stacks-docs-next or any fragment - docs.js.LICENSE.txt — build artifact, not served - entry.stacks-editor.js — 6 MB bundle, not loaded - all other entry.*.js files — not loaded by stacks-docs-next - assets/img/ (76 unreferenced images, ~2 MB) - logos/ — entire brand logos directory (56 files) - icons/ — logo glyph SVGs (6 files) - favicons/ — favicon files (3 files) - various root-level images not referenced by any fragment Remaining in assets/img/: the 10 images actually used by fragments (avatar and email preview assets). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces 38 static legacy HTML fragments with mdsvex Markdown files in src/docs/public/system/, served natively by the SvelteKit page server. Converted pages (base/ and components/ and foundation/): - base/height, margin, padding, width - components/activity-indicator, avatars, badges, bling, breadcrumbs, button-groups, cards, code-blocks, empty-states, expandable, inputs, labels, link-previews, links, loader, menus, page-titles, pagination, post-summary, progress-bars, radio, select, tables, tags, textarea, toggle-switch, topbar, uploader, user-cards, vote - foundation/accessibility, color-fundamentals, colors, typography Each MD file has YAML frontmatter (title, description, svelte URL, figma URL where available) extracted from the legacy fragment header, with the content HTML following. Also removed the `legacy:` field from structure.yaml for all 67 pages (38 newly converted + 29 that already had MD files but were being bypassed by the legacy-first serving order). 10 pages remain as legacy fragments because they contain inline <script> demos that require manual conversion to Svelte components: banners, buttons (already has full index.md), checkbox, editor, modals, navigation, notices, popovers, prose, sidebar-widgets, theming. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…r to mdsvex Establishes the pattern for converting legacy HTML docs pages to clean, maintainable mdsvex. **ClassTable.svelte** — generic CSS class documentation table: - Auto-detects which columns to show based on the data (no config needed) - Supports both component pages (modifies/description) and base utility pages (output/define/responsive) with the same component - Exports ClassTableRow type for use in page script blocks **activity-indicator.md** — prototype of the new page format: - 588 lines → 92 lines - Uses the actual ActivityIndicator Svelte component for live demos instead of pre-rendered HTML - Uses ClassTable with typed class data - Uses standard markdown headings (processed by rehype-slug + rehype-autolink-headings — no custom heading component needed) - Uses fenced code blocks for HTML usage examples The same pattern applies to all other converted pages: 1. Import ClassTable + the relevant stacks-svelte component 2. Define class data as a typed array in the script block 3. Use markdown headings + prose 4. Render live demos with Svelte components 5. Show HTML class usage in fenced code blocks Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…a11y
- Prop was named 'rows' but usage passes '{classes}', causing rows to be
undefined on render
- Added role="region" + aria-label to the scrollable wrapper so tabindex
on a non-interactive element is valid
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… order
- Code block first, then live example (matching original layout)
- Restore all compound examples:
- Standalone indicators (empty, numbers, text)
- Activity indicator on avatar (ActivityIndicator + Icon + raw s-avatar HTML)
- Activity indicator on notification icon (Icon + ActivityIndicator with positioning classes)
- Activity indicator count pill on notification icon
- Use {#each} over variants to eliminate repetition in the Variations section
- Replace @svg.* C# syntax in code blocks with commented HTML equivalents
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…kage Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Example.svelte wraps live demos in a light gray bordered container with padding, keeping examples visually distinct from prose and code blocks. Used in activity-indicator.md as the pattern to follow. Also adds TODO comments in both the script block and the two avatar examples noting where IconShieldXSm should be added once the icon is published in @stackoverflow/stacks-icons. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Changes rehype-autolink-headings from behavior:"wrap" (which made the heading text itself a silent link) to behavior:"append" (which appends the IconLink SVG after the heading text). Pairs with CSS in app.css that makes h2/h3/h4 flex containers so the icon is pushed to the right edge, matching the original legacy layout. The anchor is aria-hidden so screen readers aren't confused by the duplicate link — the heading id is the accessible anchor. This is a site-wide fix that works automatically for all mdsvex pages without needing a custom heading component. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…in breadcrumb Removes the "Copy" button from the page actions row and adds a small link icon button (s-btn__xs s-btn__clear s-btn__icon) inline at the end of the breadcrumb nav. Clicking it copies the current page URL to the clipboard using the existing copyToClipboard action. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…button Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…b copy link - Replace raw <button> with <Button link icon> using the link prop - Handle clipboard write with an inline async onclick instead of the use:copyToClipboard action (actions can't be applied to components) - Size icon with w16 h16 Stacks atomic classes — removes the custom CSS rule and the .breadcrumb-copy-link class - Remove unused copyToClipboard import and copysuccess window listener Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove flex--item from nav; nav is already a flex child via the outer div - Make nav itself d-flex ai-center g6 so items are evenly spaced and vertically aligned, including the copy link button - Remove pr6/mr6 from individual items — gap handles all spacing - Move separator before each item (index !== 0) instead of after, which is cleaner with a flex gap layout - Remove ml4 from Button — gap handles the spacing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds @stackoverflow/stacks-icons-legacy as a dependency (workspace *). IconShieldXSm lives there rather than in the main stacks-icons package. Restores the shield badge icon to both the Default and Variations avatar examples in activity-indicator.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… reordering to top Replaces md:order-first (which moved the TOC to the top of the page in column layout) with md:d-none (hides it entirely). Also removes the now- unused collapsible toggle button, isOpen state, and related Icon imports. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…prevent scroll jumping Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Use two Popover instances sharing the same reference button via elementId — one for click (popover) and one for hover (tooltip). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes 500 error caused by broken legacy stub. Full conversion using PostSummary, PostSummaryAnswer, and Tag Svelte components. ClassTable for all 21 classes. Examples for base, answered, bountied, ignored, watched, deleted, state badges, content types, excerpt sizes, small container, and answers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Functional expand/collapse via Svelte $state on all three examples. Sticky button bar uses t0 (not t64) so it scrolls with the page. Prose content embedded as HTML strings via @html for each example. ClassTable for the 2 classes. Remove legacy flag from structure.yaml. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ponents Move prose example HTML out of mdsvex template literal strings (which tripped the compiler) into ProseContent.svelte and ProseContentSandbox.svelte. prose.md now imports and renders these directly inside .s-prose containers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Unescaped { } in the JS code example were parsed as Svelte template
expressions, causing an Internal Error during SSR.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add docs-prose-example class to prose expandable containers. In app.css, reset --ff-sans/--ff-mono on .s-prose inside example containers, and explicitly reset font-family on headings (needed because the global h1–h5 rule applies Stack Sans Headline with higher specificity than the container-level custom property reset). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ainers Resetting --ff-sans alone doesn't break the inherited font-family computed from body's var(--theme-body-font-family). Setting font-family: var(--ff-sans) directly on .s-prose establishes a new font context using the locally-scoped system font stack. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ClassTable for 4 classes. Info and warning Notice components. Raw HTML example using Icon components for Award and Plus icons. Remove legacy flag from structure.yaml. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ClassTable for classes, cell widths, JS data attributes, and atomic classes. All table examples retained exactly with no custom styling added. Icon components for sortable table arrows. JS sorting example includes data-controller for when Stacks JS is available. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
IconArrowDownSm, IconArrowUpSm, IconArrowUpDownSm only exist in the legacy icons package, not in the current stacks-icons. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…mples Svelte's template parser doesn't handle > inside quoted attribute values, causing a 500. Use > so the parser is happy and the browser still decodes it to the correct click->s-table#sort Stimulus action. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Svelte's HTML parser requires explicit tbody — tr directly inside table without thead/tbody/tfoot causes a parse/runtime error. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Svelte components nested inside raw HTML table elements cause a runtime SSR error. Replace with Unicode arrows (↑ ↓ ↕) inside plain span elements, and drop the stacks-icons-legacy import. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ClassTable expects the prop named 'classes'. Using shorthand {widths}
passed it as widths= (unknown prop) leaving classes=undefined, causing
classes.some() to throw during SSR.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Revert to the state that actually works:
- Restore stacks-icons-legacy import and Icon components for sort arrows
- Keep > escaping in data-action (Svelte template parser requirement)
- Keep explicit <tbody> in cell width tables (Svelte HTML parser requirement)
- Keep classes={widths}/classes={atomic} prop names (the actual fix)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Icon components inside <th> elements cause SSR errors. Using inline SVG bypasses that — the svg element is raw HTML, not a Svelte component. Replaces Unicode fallback arrows with the correct Stacks iconArrowDownSm and iconArrowUpDownSm icons from stacks-icons-legacy. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace static HTML example with TableSortDemo.svelte, which implements the same behaviour as the Stacks s-table Stimulus controller using Svelte 5 reactive state — clicking column headers sorts rows, toggles direction, and shows the correct sort icon. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ClassTable for 9 classes. Tag Svelte component for all examples (default, dismissable, sponsor, moderator, required, watched, ignored). Sizes section shows all three variants with ff-mono labels. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…able No anchor links in this table so the classes serve no purpose. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Code block + ExampleTable with Tag components in the example column, matching the badges sizes section layout. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ClassTable for 2 classes. Raw HTML for basic toggle examples (no Svelte component exists). Icon components from stacks-icons for the multiple-option toggle examples. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- docs-h2: add margin-bottom var(--su16) - docs-section[data-heading-rank]: reduce margin-top to var(--su32) - first docs-h3 in a docs-section: margin-top var(--su24) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
.docs-h2 + .docs-section > .docs-h3 targets only the h3 whose section immediately follows an h2 with no content between them, giving su24 of space. When prose separates h2 from h3, the full su48 applies. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Also refines page header styles (description fc-black-500/fs-title, breadcrumb fw-bold, copy-link button color) and adds docs-copy typography to notice paragraphs and h4 margin-bottom. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Converts legacy component documentation pages in
stacks-docs-nextfrom the old rendered HTML format to clean mdsvex, usingClassTable,ExampleTable,Example, and@stackoverflow/stacks-sveltecomponents throughout. Also includes a series of layout and typography refinements to the doc page shell.Related Issue
STACKS-843
Changes
packages/stacks-docs-next
structure.yaml: removedlegacy:keys for converted pages, added navigation entries for new and removed-in-v3 pagesapp.css: refined docs heading sizes/weights/spacing, section margins, s-prose font isolation in example containers, notice paragraph typography, copy-link button color+page.svelte: page description usesfs-title/fc-black-500, breadcrumb links usefw-bold, copy-link button styledfc-black-400/h:fc-black-600TableSortDemo.svelte: new interactive sort demo component for the tables pageProseContent.svelte/ProseContentSandbox.svelte: prose example HTML extracted to dedicated components to avoid mdsvex template-literal parsing issuesTesting
Check each converted page in the dev server (
pnpm --filter stacks-docs-next dev). All pages should render without 500 errors, show correct class tables and live examples, and match the layout of the legacy docs.